package cn.com.hhrcw.job;

import cn.com.hhrcw.area.entity.SysArea;
import cn.com.hhrcw.area.service.ISysAreaService;
import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.utils.RedisLockUtils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @program: recruit-boot-parent
 * @description: 统计各个地区数据
 * @author: JD
 * @create: 2020-11-18 16:21
 **/
@Component("AreaStatisticsTask")
@Slf4j
public class AreaStatisticsTask implements Job {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private IOpJobService jobService;

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    private IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    private IOpEntryHistoryService entryHistoryService;

    @Autowired
    private IStatisticsAreaService statisticsAreaService;

    @Autowired
    private ISysAreaService sysAreaService;

    @Override
    public void execute(JobExecutionContext context) {
        String key1 = "JOB_AREA__TASK";
        try {
            if (RedisLockUtils.tryLock(key1, 1, TimeUnit.MINUTES)) {

                log.debug("---------统计各地区招聘数据开始---------");
                //获取所有地区
                List<SysArea> areas = sysAreaService.lambdaQuery().notIn(SysArea::getLevel, "district", "street").list();
                List<StatisticsArea> list = Lists.newArrayList();
                areas.forEach(e -> {
                    StatisticsArea statisticsArea = new StatisticsArea();
                    statisticsArea.setId(e.getId());
                    statisticsArea.setLevel(e.getLevel());
                    statisticsArea.setCenter(e.getCenter());
                    statisticsArea.setDelFlag(false);
                    //地区名
                    statisticsArea.setName(e.getName());
                    statisticsArea.setResumeCount(0);
                    statisticsArea.setEntryRate(new BigDecimal(0));
                    statisticsArea.setFeedbackRate(new BigDecimal(0));
                    statisticsArea.setViewRate(new BigDecimal(0));
                    statisticsArea.setTotalJobCount(0);
                    statisticsArea.setThisDayJobCount(0);
                    statisticsArea.setThisMonthJobCount(0);
                    statisticsArea.setThisYearJobCount(0);
                    //收到简历数量
                    //本地区下职位
                    List<OpJob> jobs = jobService.lambdaQuery().eq(OpJob::getDelFlag, false).and(ew -> {
                        ew.eq(OpJob::getJobProvince, e.getId()).or().eq(OpJob::getJobCity, e.getId());
                        return ew;
                    }).select(OpJob::getDeliveryCount, OpJob::getId).list();
                    if (CollUtil.isNotEmpty(jobs)) {
                        Object[] jobIds = jobs.stream().map(OpJob::getId).toArray();
                        statisticsArea.setTotalJobCount(jobs.size());
                        //entryRate 入职率 实际入职人数/总发出入职邀请人数
                        //当前地区总投递量
                        Integer resumeCount = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).in(OpDeliveryHistory::getJobId, jobIds).count();
                        statisticsArea.setResumeCount(resumeCount);
                        // 反馈率
                        if (resumeCount > 0) {
                            //有反馈的投递记录
                            Integer total = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).gt(OpDeliveryHistory::getState, 1).eq(OpDeliveryHistory::getScreenFlag, true).in(OpDeliveryHistory::getJobId, jobIds).count();
                            statisticsArea.setFeedbackRate(NumberUtil.round(NumberUtil.div(total, resumeCount).doubleValue() * 100, 2));
                        }

                        //viewRate 面试率
                        //发出面试数量
                        Integer sendViewCount = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).in(OpInterviewHistory::getJobId, jobIds).count();
                        if (sendViewCount > 0) {
                            //接收数量
                            Integer acceptCount = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).in(OpInterviewHistory::getJobId, jobIds).eq(OpInterviewHistory::getOutLineState, 1).count();
                            statisticsArea.setViewRate(NumberUtil.round(NumberUtil.div(acceptCount, sendViewCount).doubleValue() * 100, 2));
                        }

                        //发出邀请数量
                        Integer sendCount = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getDelFlag, false).in(OpEntryHistory::getJobId, jobIds).count();
                        if (sendCount > 0) {
                            //查询入职数量
                            Integer entryCount = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getDelFlag, false).eq(OpDeliveryHistory::getState, 6).in(OpDeliveryHistory::getJobId, jobIds).count();
                            statisticsArea.setEntryRate(NumberUtil.round(NumberUtil.div(entryCount, sendCount).doubleValue() * 100, 2));
                        }

                        //thisDayJobCount 今日职位数量
                        Integer todayJobCount = this.jobService.lambdaQuery().eq(OpJob::getDelFlag, false)
                                .and(ew -> {
                                    ew.eq(OpJob::getJobProvince, e.getId()).or().eq(OpJob::getJobCity, e.getId());
                                    return ew;
                                })
                                .between(OpJob::getCreateTime, DateUtil.beginOfDay(DateUtil.date()), DateUtil.endOfDay(DateUtil.date()))
                                .count();
                        statisticsArea.setThisDayJobCount(todayJobCount);

                        //thisMonthJobCount 本月职位数
                        Integer thisMonthCount = this.jobService.lambdaQuery().eq(OpJob::getDelFlag, false)
                                .and(ew -> {
                                    ew.eq(OpJob::getJobProvince, e.getId()).or().eq(OpJob::getJobCity, e.getId());
                                    return ew;
                                })
                                .between(OpJob::getCreateTime, DateUtil.beginOfMonth(DateUtil.date()), DateUtil.endOfMonth(DateUtil.date()))
                                .count();
                        statisticsArea.setThisMonthJobCount(thisMonthCount);

                        //thisYearJobCount 本年度
                        Integer thisYearCount = this.jobService.lambdaQuery().eq(OpJob::getDelFlag, false)
                                .and(ew -> {
                                    ew.eq(OpJob::getJobProvince, e.getId()).or().eq(OpJob::getJobCity, e.getId());
                                    return ew;
                                })
                                .between(OpJob::getCreateTime, DateUtil.beginOfYear(DateUtil.date()), DateUtil.endOfYear(DateUtil.date())).count();
                        statisticsArea.setThisYearJobCount(thisYearCount);
                    }
                    statisticsArea.setCreateBy("job");
                    statisticsArea.setUpdateTime(new Date());
                    list.add(statisticsArea);
                });
                if (CollUtil.isNotEmpty(list)) {
                    statisticsAreaService.saveOrUpdateBatch(list);
                }
                log.debug("---------统计各地区招聘数据结束---------");
            }
        } catch (Exception e) {

        } finally {
            RedisLockUtils.unLock(key1);
        }
    }
}
